package com.review.backpack_01;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

public class BP08_2 {
    //8. 求背包问题的方案
    //输出最优方案
    public static int knapsackProblem(int[] c, int[] v, int cap) {
        // 记录最大价值
        int[][] dp = new int[c.length][cap + 1];
        // 记录当前物品是否被选择
        int[][] choose = new int[c.length][cap + 1];

        for (int i = cap; i >= c[0]; i--) {
            dp[0][i] = v[0];
            choose[0][i] = 1;
        }
        for (int i = 1; i < c.length; i++) {
            for (int j = 1; j <= cap; j++) {
                if (j >= c[i]) {
                    if (dp[i - 1][j] <= dp[i - 1][j - c[i]] + v[i]) {
                        // 选择当前物品为最优解
                        dp[i][j] = dp[i - 1][j - c[i]] + v[i];
                        choose[i][j] = 1;
                    } else {
                        dp[i][j] = dp[i - 1][j];
                    }
                } else {
                    dp[i][j] = dp[i - 1][j];
                }
            }
        }
        // 反推出物品编号
        List<Integer> list = new LinkedList<>();
        int i = c.length - 1, V = cap;
        while (i >= 0) {
            if (choose[i][V] != 0) {
                list.add(i);
                V -= c[i];
            }
            i--;
        }
        Collections.reverse(list);
        System.out.println("最优方案选择：" + list);

        return dp[dp.length - 1][dp[0].length - 1];
    }

    public static void main(String[] args) {
        System.out.println(knapsackProblem(new int[]{1, 3, 4}, new int[]{15, 20, 30}, 4));
    }
}
